package generic;

/**
 * @author ChangLiang
 * @date 2021/2/1
 */
public class CaptureConversion {

    /**
     * f1()中的类型参数都是确切的，没有通配符或边界。
     * 在f2()中， Holder参数是一个无界通配符，因此它看起来是未知的。
     *
     * 但是，在f2()中， f1()被调用， 而f1()需要一个已知参数。
     *
     * 这里所发生的是：参数类型在调用f2()的过程中被捕获，因此它可以在对f1()的调用中被使用。
     * @param holder
     * @param <T>
     */

    static <T> void f1(Holder<T> holder) {
        T t = holder.get();
        System.out.println(t.getClass().getSimpleName());
    }

    static void f2(Holder<?> holder) {
        // Call with captured type
        f1(holder);
    }

//    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        Holder raw = new Holder<>(1);
        // Produces warnings
        f1(raw);

        // No warnings
        f2(raw);
        Holder rawBasic = new Holder();
        // Warning
        rawBasic.set(new Object());
        // No warnings
        f2(rawBasic);
        // Upcast to Holder<?>, still figures it out:
        Holder<?> wildcarded = new Holder<Double>(1.0);
        f2(wildcarded);
    }
}
